﻿import json
from abc import ABC, abstractmethod
from collections import namedtuple

import requests
import os
import pprint

from tqdm import tqdm

MusicEntry = namedtuple('MusicEntry', ['author', 'title', 'url'])
CONFIG_FILE = 'config.json'
DEFAULT_DOWNLOAD_PATH = os.path.dirname(os.path.abspath(__file__))  # 默认路径为脚本所在目录
current_music_source = 'qq'




def display_music_sources(data_sources_map):
    """显示音乐源选项"""
    for index, (key, value) in enumerate(data_sources_map.items(), start=1):
        print(f"{index}. {value}")


def select_music_source(data_sources_map):
    """选择音乐源并设置"""
    while True:
        display_music_sources(data_sources_map)
        try:
            choice = int(input("请输入您选择的平台序号："))
            setMusicsource(choice)
            return
        except (ValueError, IndexError):
            print("输入错误，请输入有效的序号。")


def search_and_select_music(music_name):
    """搜索音乐并选择下载"""
    global path
    music_list = search_music(music_name)
    if not music_list:
        print('"ㄟ( ▔, ▔ )ㄏ 没有找到相关信息"')
        return
    for index, entry in enumerate(music_list, start=1):
        print(f"{index}. {entry.title} - {entry.author}")
        values = int(input('请输入下载序号: '))
        if 1 <= values <= len(music_list):
                selected_item = music_list[values - 1]
                # 确保selected_item有"title"和"url"字段，对于NamedTuple这已经是确定的
                print('需要更新下载路径吗？ y/n ')
                choose = input()
                if choose == 'y':
                  path = input('请输入新的保存路径:')
                  update_download_path(path)
                else:
                 path = load_download_path()
                print('已使用路径:', path)
                download(entry.url,entry.title,path)
                print('请问是否继续下载？ y/n')
                user_input = input("").strip().lower()  # 移除前后空格并转为小写
                if user_input == 'y':
                      continue
                elif user_input == 'n':
                    print('程序已退出。')
                    exit(0)

                else:
                    print("无效输入，请仅输入'y'或'n'。")
        else:
            print('输入错误，请输入有效的序号。')

def setMusicsource(more):
    """
    通过数字选择并设置音乐源
    :param more: 用户输入的选择序号
    """
    global current_music_source

    # 确保more是整数
    more = int(more)

    # 打印音乐源选项（这部分可以移至外部，确保用户在选择前能看到选项）
    for index, (key, value) in enumerate(data_sources_map.items(), start=1):
        print(f"{index}: {value}")

    # 检查用户输入的选择是否有效
    if 1 <= more <= len(data_sources_map):
        selected_key = list(data_sources_map.keys())[more - 1]
        current_music_source = selected_key
        print(f"音乐源已设置为：{data_sources_map[current_music_source]}")
    else:
        print("错误：输入的数字无效。请重新选择。")

def ensure_config_file_exists():
    """确保配置文件存在，如果不存在则创建并设置默认路径"""
    if not os.path.exists(CONFIG_FILE):
        with open(CONFIG_FILE, 'w') as file:
            json.dump({'download_path': DEFAULT_DOWNLOAD_PATH}, file, indent=4)
            print(f"配置文件已创建，使用默认下载路径：{DEFAULT_DOWNLOAD_PATH}")

def load_download_path():
    """加载下载路径，如果配置文件存在则返回记录的路径，否则返回默认路径"""
    try:
        with open(CONFIG_FILE, 'r') as file:
            config = json.load(file)
            path = config.get('download_path', DEFAULT_DOWNLOAD_PATH)
            return os.path.abspath(path)
    except FileNotFoundError:
        ensure_config_file_exists()  # 如果文件不存在，则创建并设置默认路径
        return DEFAULT_DOWNLOAD_PATH

def update_download_path(new_path):
    with open(CONFIG_FILE, 'w') as file:
        json.dump({'download_path': os.path.abspath(new_path)}, file, indent=4)
    print(f"下载路径已更新为: {new_path}")


# url 下载地址 name 歌曲名 path 下载路径
def download(url,name,path):
    res = requests.get(url)
    music_connect = res.content
    data_size = round(int(res.headers['Content-Length']) / 1024 / 1024)  # 注意这里也要确保Content-Length转换为int类型
    with open(f"{path}/{name}.mp3", 'wb') as f:
        for data in tqdm(iterable=res.iter_content(1024 * 1024), total=data_size, desc='正在下载', unit='MB'):
                    f.write(data)
    print(f'{name}下载成功！')
# name 歌曲名
# more 音乐数据源
def search_music(name,more = current_music_source):
    music_list = []
    count = 0
    for i in range(1, 10):
        data = {
            'input': name,
            'filter': 'name',
            'type': more,
            'page': i,
        }
        res = requests.post('https://music.txqq.pro/', headers=headers, data=data)
        datas = json.loads(res.text)

        data_list = datas['data']
        for item in data_list:
            author = item.get('author', '未知')
            title = item.get('title', '未知')
            url = item.get('url', '')
            if url:
                count+=1
                print(f"{count}.{title} - {author}")
                music_list.append(MusicEntry(author, title, url))  # 使用namedtuple代替元组
        return music_list

headers = {
    'accept': 'application/json, text/javascript, */*; q=0.01',
    'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,ru;q=0.5',
    'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'origin': 'https://music.txqq.pro',
    'priority': 'u=1, i',
    'referer': 'https://music.txqq.pro/?name=%E6%99%B4%E5%A4%A9&type=qq',
    'sec-ch-ua': '"Microsoft Edge";v="125", "Chromium";v="125", "Not.A/Brand";v="24"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'same-origin',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36 Edg/125.0.0.0',
    'x-requested-with': 'XMLHttpRequest',
}

# data = {
#     'input': '晴天',
#     'filter': 'name',
#     'type': 'qq',
#     'page': '2',
# }

data_sources_map = {
    'qq': '腾讯QQ音乐',
    'kugou': '酷狗音乐',
    'kuwo': '酷我音乐',
    'baidu': '千千音乐',
    '1ting': '一听音乐',
    'migu': '咪咕音乐',
    'lizhi': '荔枝FM',
    'qingting': '蜻蜓FM',
    'ximalaya': '喜马拉雅',
    '5singyc': '5sing原创',
    '5sing_cover': '5singfc',
    'kg': '全民K歌',
}
# response = requests.post('https://music.txqq.pro/', headers=headers, data=data)
# data = json.loads(response.text)
# pprint.pprint(data)

if __name__ == '__main__':

    while True:

     select_music_source(data_sources_map)
     print('输入音乐名称:')
     music_name = input()
     search_and_select_music(music_name)

# data_list = data['data']
# for i in data_list:
#     title = i['title']
#     url = i['url']
#     print(title,url)
